package org.trc.traffic.estimation;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import org.geotools.data.shapefile.shp.ShapefileException;
import org.opengis.geometry.MismatchedDimensionException;
import org.opengis.referencing.operation.TransformException;
import org.trc.io.DBAccess;
import org.trc.io.DBUpdate;
import org.trc.network.Edge;
import org.trc.network.Network;
import org.trc.traffic.BasicLinkTraffic;
import org.trc.trajectory.Trajectory;
import org.trc.trajectory.TrajectoryPoint;
import org.trc.trajectory.Trip;

public class TrafficEstimation {
	
	//读取每辆车的数据，获取TrajectoryPoint与Trajectory对象，通过Trip计算LinkTraffic，并填充traffic_basic表
	public static void traj2linkTraffic(File csvFile, Network road) throws ShapefileException, IOException, MismatchedDimensionException, TransformException{
		Trajectory traj = DBAccess.getTrajectoryByCSVFile(csvFile);
		ArrayList<BasicLinkTraffic> linkTrafficList = new ArrayList<BasicLinkTraffic>();
		for(Trip trip : traj.getTrip()){
			ArrayList<BasicLinkTraffic> linkTraffics = extractBasicLinkTraffic(trip,road);
			linkTrafficList.addAll(linkTraffics);
		}
		DBUpdate.populateFcdCubeBasicFactTable(linkTrafficList, "traffic_basic");
	}
    
	//通过Trip来获取LinkTraffic
	public static ArrayList <BasicLinkTraffic> extractBasicLinkTraffic(Trip trip, Network road){
		ArrayList <BasicLinkTraffic> linkTrafficList = new ArrayList <BasicLinkTraffic> ();
		
		TrajectoryPoint prePoint = null;
		TrajectoryPoint nextPoint = null;
		
		String preCommonNodeID = null;
		int preEnterTime = 0;
		
		for(int i = 0; i < trip.points.size()- 1; i++) {
			prePoint = trip.points.get(i);
			nextPoint = trip.points.get(i+1);			
			if(prePoint.linkID.equals(nextPoint.linkID)) //位于同一路段
				continue;	
			String curCommonNodeID  = road.getCommonPoint(prePoint.linkID, nextPoint.linkID);
			if(curCommonNodeID != null) {//如果位于邻接路段，计算进入或离开的时间
				Edge preEdge = road.getEdgeById(prePoint.linkID);
				Edge curEdge = road.getEdgeById(nextPoint.linkID);
				double preDistance =  preEdge.getLinearDistance(curCommonNodeID, prePoint.geom.getCoordinate());
				double curDistance = curEdge.getLinearDistance(curCommonNodeID, nextPoint.geom.getCoordinate());				
				int preTime = prePoint.seconds;
				int curTime = nextPoint.seconds;				
				int curEnterTime = (int) ((preTime*curDistance + curTime*preDistance)/(preDistance + curDistance));
				if(preEdge.getAnotherNodeId(curCommonNodeID).equals(preCommonNodeID)) {//生成BasicLinkTraffic
					int travelTime = Math.abs(curEnterTime - preEnterTime);
					float travelSpeed = (float) ((preEdge.length/travelTime) * 3.6);
					BasicLinkTraffic linkTraffic = new BasicLinkTraffic(trip.carID, preEdge.id, preEnterTime, travelTime, travelSpeed);
/*					System.out.println(
					"car: " + linkTraffic.carID + ", " 
					+ "tripID: " + trip.tripID  + ", " 
					+ "linkID: " + linkTraffic.linkID + ", " 
					+ "enterTime: " + linkTraffic.getTimeString() + ", " 
					+ "travleTime : " + travelTime + ", " 
					+ "speed: "+ travelSpeed);*/
					linkTrafficList.add(linkTraffic);
				}
				preCommonNodeID = curCommonNodeID;
				preEnterTime = curEnterTime;
			}
		}
		
		return linkTrafficList;
	}

}
